//
// Created by kyle on 25-7-16.
//

#include "FontRenderer.h"

#include <fstream>
#include <vector>

#include "FrameBuffer.h"

bool FontRenderer::init() {
    // 初始化FreeType库
    if (FT_Init_FreeType(&library_)) {
        std::cerr << "FreeType initialization failed\n";
        return false;
    }

    // 查找并加载中文字体
    const auto chinese_path = find_system_chinese_font();
    if (!chinese_path.empty()) {
        std::cout << "Loading Chinese font: " << chinese_path << "\n";
        if (!load_font(chinese_path, chinese_face_, "Chinese")) {
            std::cerr << "Warning: Chinese font load failed, using main font for Chinese\n";
        }
    } else {
        std::cerr << "Warning: No system Chinese font found\n";
        FT_Done_FreeType(library_);
        library_ = nullptr;
        return false;
    }

    return true;
}

FontRenderer::~FontRenderer() {
    // 使用智能指针自动管理资源
    chinese_face_.reset();

    if (library_) {
        FT_Done_FreeType(library_);
        library_ = nullptr;
    }
}

bool FontRenderer::load_font(const std::string &path, UniqueFTFace &face, const std::string &type) const {
    // 检查文件是否存在且可读
    std::error_code ec;
    if (!fs::exists(path, ec) || !fs::is_regular_file(path, ec)) {
        std::cerr << "Error: Font file not found - " << path << "\n";
        return false;
    }

    std::ifstream file(path, std::ios::binary);
    if (!file.is_open()) {
        std::cerr << "Error: No read permission for font - " << path << "\n";
        return false;
    }

    // 加载字体
    FT_Face raw_face = nullptr;
    if (FT_New_Face(library_, path.c_str(), 0, &raw_face)) {
        std::cerr << "Error: Failed to load " << type << " font: " << path << "\n";
        return false;
    }

    face.reset(raw_face);
    std::cout << "Loaded " << type << " font: " << path << "\n";
    return true;
}

std::string FontRenderer::find_system_chinese_font() {
    const std::vector<std::string> chinese_fonts = {
        "uming.ttc", "simfang.ttf", "simsun.ttc", "msyh.ttf", "simhei.ttf",
        "HarmonyOS_Sans_SC_Regular.ttf", "NotoSansCJK-Regular.ttf",
        "DroidSansFallback.ttf", "WenQuanYiMicroHei.ttf",
        "ukai.ttc"
    };

    const std::vector<fs::path> font_dirs = {
        "/opt/aku/web/",
        "/usr/share/fonts/",
        "/usr/local/share/fonts/",
        "/usr/share/fonts/truetype/",
        "/usr/share/fonts/opentype/",
        "/usr/share/fonts/TTF/",
        "/usr/share/fonts/OTF/",
        "/usr/local/share/fonts/truetype/",
        "/usr/local/share/fonts/opentype/",
        "/mnt/c/Windows/Fonts/" //添加 WSL 兼容路径
    };

    for (const auto &dir: font_dirs) {
        std::error_code ec;
        if (!fs::exists(dir, ec) || !fs::is_directory(dir, ec)) continue;

        for (const auto &entry: fs::recursive_directory_iterator(dir, ec)) {
            if (ec) continue;

            if (!entry.is_regular_file(ec)) continue;

            const auto &path = entry.path();
            const std::string filename = path.filename().string();

            for (const auto &font: chinese_fonts) {
                if (filename.find(font) != std::string::npos) {
                    return path.string();
                }
            }
        }
    }

    return "";
}

void FontRenderer::draw_text(std::shared_ptr<FrameBuffer> fb, const std::string &text, int x, int y,
                             uint8_t r, uint8_t g, uint8_t b, int font_size, bool is_chinese) const {
    FT_Face face = chinese_face_.get();

    FT_Set_Pixel_Sizes(face, 0, font_size);

    int pen_x = x;
    int pen_y = y;

    for (size_t i = 0; i < text.size();) {
        uint32_t unicode_char = 0;
        size_t char_len = 0;

        const uint8_t lead = static_cast<uint8_t>(text[i]);
        if ((lead & 0x80) == 0) {
            // ASCII
            unicode_char = lead;
            char_len = 1;
        } else if ((lead & 0xE0) == 0xC0) {
            // 2-byte UTF-8
            if (i + 1 >= text.size()) break;
            unicode_char = ((lead & 0x1F) << 6) | (text[i + 1] & 0x3F);
            char_len = 2;
        } else if ((lead & 0xF0) == 0xE0) {
            // 3-byte UTF-8
            if (i + 2 >= text.size()) break;
            unicode_char = ((lead & 0x0F) << 12) |
                           ((static_cast<uint8_t>(text[i + 1]) & 0x3F) << 6) |
                           (static_cast<uint8_t>(text[i + 2]) & 0x3F);
            char_len = 3;
        } else {
            ++i;
            continue;
        }

        if (FT_Load_Char(face, unicode_char, FT_LOAD_RENDER | FT_LOAD_TARGET_MONO)) {
            i += char_len;
            continue;
        }

        FT_GlyphSlot glyph = face->glyph;
        FT_Bitmap &bitmap = glyph->bitmap;

        for (int row = 0; row < bitmap.rows; ++row) {
            for (int col = 0; col < bitmap.width; ++col) {
                const int byte_idx = row * bitmap.pitch + col / 8;
                const int bit_idx = 7 - (col % 8);

                if (bitmap.buffer[byte_idx] & (1 << bit_idx)) {
                    fb->write_pixel(
                        pen_x + col + glyph->bitmap_left,
                        pen_y + glyph->bitmap_top - row,
                        r, g, b);
                }
            }
        }

        pen_x += glyph->advance.x >> 6;
        i += char_len;
    }
}


double FontRenderer::get_font_radio() {
    FT_Face face = get_face(true);
    // 设置字体大小
    if (FT_Set_Pixel_Sizes(face, 0, 72)) {
        throw std::runtime_error("无法设置字体大小");
    }
    // 获取字体度量信息
    int width = face->size->metrics.max_advance >> 6; // 转换为像素
    int ascender = face->size->metrics.ascender >> 6;
    int descender = face->size->metrics.descender >> 6;
    int lineHeight = ascender - descender;

    return 1.0 * lineHeight / width;
}

bool FontRenderer::is_chinese_char(uint32_t char_code) {
    // 中文字符的Unicode范围
    return (char_code >= 0x4E00 && char_code <= 0x9FFF) ||
           (char_code >= 0x3400 && char_code <= 0x4DBF) ||
           (char_code >= 0x20000 && char_code <= 0x2A6DF) ||
           (char_code >= 0x2A700 && char_code <= 0x2B73F);
}

/**
    * 渲染文字
    * @param fb
    * @param char_code
    * @param x
    * @param y
    * @param color
    * @param font_size
    * @param is_chinese
    */
void FontRenderer::render_char(std::shared_ptr<FrameBuffer> fb, uint32_t char_code, int x, int y,
                               uint16_t color, int font_size, bool is_chinese) {
    FT_Face face = get_face(is_chinese);
    if (!face) return;

    FT_Set_Pixel_Sizes(face, 0, font_size);
    if (FT_Load_Char(face, char_code, FT_LOAD_RENDER | FT_LOAD_TARGET_MONO)) {
        return;
    }

    FT_GlyphSlot glyph = face->glyph;
    FT_Bitmap &bitmap = glyph->bitmap;

    for (int row = 0; row < bitmap.rows; ++row) {
        for (int col = 0; col < bitmap.width; ++col) {
            int byte_idx = row * bitmap.pitch + col / 8;
            int bit_idx = 7 - (col % 8);

            if (bitmap.buffer[byte_idx] & (1 << bit_idx)) {
                fb->write_pixel(x + col + glyph->bitmap_left,
                                y + glyph->bitmap_top - row,
                                color >> 16, color >> 8, color >> 0);
            }
        }
    }
}
